/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.imsx.controller.util;

import com.imsx.model.Cliente;
import com.imsx.model.Item;
import com.imsx.model.Orden;
import com.imsx.model.Producto;
import java.io.BufferedReader;
import java.io.IOException;

import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;
import com.mongodb.util.JSON;
import java.util.ArrayList;
import java.util.Arrays;
import org.bson.types.ObjectId;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 *
 * @author mivkys
 */
public class Driver {

    public static void main(String[] args) throws IOException {
        //DB dB = new Mongo().getDB("amazondb");
        MongoClient mongoClient = new MongoClient(Arrays.asList(
                    new ServerAddress("192.168.1.101", 27017),
                    new ServerAddress("192.168.1.102", 27017),
                    new ServerAddress("192.168.1.103", 27017)));

        DB dB = mongoClient.getDB("amazondb");
//        ArrayList<Object> productos = new ArrayList<Object>();
//        Producto p1 = new Producto((new ObjectId()).toString(), "Iphone", 599.99, 13);
//        productos.add(p1);
//        Item i1 = new Item(p1, 2);
//        
//        Producto p2 = new Producto((new ObjectId()).toString(), "Mac", 1199.45, 10);
//        productos.add(p2);
//        Item i2 = new Item(p2, 4);
//        
//        Producto p3 = new Producto((new ObjectId()).toString(), "Ipad", 799.65, 11);
//        productos.add(p3);
//        Item i3 = new Item(p3, 5);
//        
//        Orden o = new  Orden((new ObjectId()).toString());
//        o.setItems(i1);
//        o.setItems(i2);
//        //o.setItems(i3);
//        ArrayList<Object> clientes = new ArrayList<Object>();
//        ArrayList<Object> ordens = new ArrayList<Object>();
//        ordens.add(o);
////        
//        Map <String, Orden> ordenes = new HashMap<String, Orden>();
//        ordenes.put(o.getOrdenId(), o);
//        Cliente c = new Cliente((new ObjectId()).toString(), "Miguel Saca", ordenes);
//        clientes.add(c);
//        
//        //insert(productos, dB.getCollection("producto"));
//        //insert(ordens, dB.getCollection("orden"));
//        //DBCollection channelDBCollection = dB.getCollection("cliente");
//        //insert(clientes, dB.getCollection("cliente"));
//        
//        ///
//        p2.setStock(5);
//        p2.setProductoId("548dd80de6c0640389d1a43a");
//       updateProducto(p2,dB);
        //updateComprasCliente(dB,new BasicDBObject("_id", new ObjectId("548dd80de6c064038dd1a43a")),new Orden("548de065867c640330504391"));
//        DBCollection channelDBCollection = dB.getCollection("producto");
//        BasicDBObject query = new BasicDBObject("titulo", "Ipad");
//
//        Map<String, Producto> productos = new HashMap<>();
//        Map<String, Orden> ordenes = new HashMap<>();
//        findProducto(dB, null, productos);
//        findOrden(dB, new BasicDBObject("_id", new ObjectId("548ab13f689764035170d364")), ordenes, productos);
//        System.out.println(ordenes.get("548ab13f689764035170d364").getTotal());
//convertirJSON(null).size();
        Map<String, Producto> items;
        items = new HashMap<>();
        findProducto(dB, null, items);
    }

    public static void insert(ArrayList<Object> data, DBCollection amazonDBCollection) throws IOException {
        DBObject amazonDBObject = new BasicDBObject();
        for (Object object : data) {
            if (object instanceof Producto) {
                Producto p = (Producto) object;
                amazonDBObject.put("_id", new ObjectId(p.getProductoId()));
                amazonDBObject.put("titulo", p.getTitulo());
                amazonDBObject.put("precio", p.getPrecio());
                amazonDBObject.put("stock", p.getStock());
            } else if (object instanceof Cliente) {

                Cliente c = (Cliente) object;
                amazonDBObject.put("nombre", c.getNombre());
                BasicDBList atrib3DBList = new BasicDBList();
                DBObject atrib3DBObject = null;
                Iterator it = (c.getOrdenes()).keySet().iterator();
                while (it.hasNext()) {
                    String key = it.next().toString();
                    Orden orden = (c.getOrdenes()).get(key);

                    atrib3DBObject = new BasicDBObject();
                    atrib3DBObject.put("orden", new ObjectId(orden.getOrdenId()));
                    atrib3DBList.add(atrib3DBObject);
                }
                amazonDBObject.put("compras", atrib3DBList.toArray());

            } else if (object instanceof Orden) {

                Orden o = (Orden) object;
                amazonDBObject.put("_id", new ObjectId(o.getOrdenId()));
                BasicDBList atrib3DBList = new BasicDBList();
                DBObject atrib3DBObject = null;
                Iterator it = (o.getItems()).keySet().iterator();
                while (it.hasNext()) {
                    String key = it.next().toString();
                    Item items = (o.getItems()).get(key);

                    atrib3DBObject = new BasicDBObject();
                    atrib3DBObject.put("producto", new ObjectId(items.getItemId()));
                    atrib3DBObject.put("cantidad", items.getCantidad());
                    atrib3DBList.add(atrib3DBObject);
                }
                amazonDBObject.put("items", atrib3DBList.toArray());
                amazonDBObject.put("total", o.getTotal());
                amazonDBObject.put("fechaCompra", o.getFechaCompra());

            } else {
                return;
            }

            amazonDBCollection.insert(amazonDBObject);
        }
    }

    private static void delete(BufferedReader bufferedReader, DBCollection amazonDBCollection) throws IOException {
        System.out.println("que atributo? ");
        DBObject basicDBObject = new BasicDBObject();
        basicDBObject.put("atributo1", bufferedReader.readLine());
        amazonDBCollection.remove(basicDBObject);
    }

    public static void updateProducto(Producto producto, DB dB) throws IOException {
        DBCollection channelDBCollection = dB.getCollection("producto");
        DBObject fromDBObject = new BasicDBObject();
        fromDBObject.put("_id", new ObjectId(producto.getProductoId()));
        
        DBObject toDBObject = new BasicDBObject();
        toDBObject.put("stock", producto.getStock());
        
        DBObject updateDBObject = new BasicDBObject();
        updateDBObject.put("$set", toDBObject);
        channelDBCollection.update(fromDBObject, updateDBObject);
    }
    public static void updateComprasCliente(DB dB,BasicDBObject incidentObject, Orden orden ){
        DBCollection channelDBCollection = dB.getCollection("cliente");
        BasicDBObject commentObject = new BasicDBObject();
        commentObject.put("orden", new ObjectId(orden.getOrdenId()));
        channelDBCollection.update(incidentObject, 
                new BasicDBObject("$push", new BasicDBObject("compras", commentObject)),
                false,false);
    }
    private static DBCursor findAll(DBCollection amazonDBCollection) {
        DBCursor dbCursor = amazonDBCollection.find();
        //while (dbCursor.hasNext()) System.out.println(dbCursor.next());
        return dbCursor;
    }
    
    public static void findProducto(DB dB, BasicDBObject basicDBObject, Map<String, Producto> producto) {
        DBCollection channelDBCollection = dB.getCollection("producto");
        DBCursor dbCursor;
        if (basicDBObject == null) {
            dbCursor = channelDBCollection.find();
        } else {
            dbCursor = channelDBCollection.find(basicDBObject);
        }
        if (producto != null) {
            while (dbCursor.hasNext()) {
                Map map = (dbCursor.next()).toMap();
                producto.put(map.get("_id").toString(), new Producto(map.get("_id").toString(), map.get("titulo").toString(), Double.parseDouble(map.get("precio").toString()), Integer.parseInt(map.get("stock").toString())));
              //  System.out.println("Codigo antes: "+(producto.get(map.get("_id").toString())).getProductoId());
            }
        }
    }

    public static void findOrden(DB dB, BasicDBObject basicDBObject, Map<String, Orden> ordenes, Map<String, Producto> productos) {
        DBCollection channelDBCollection = dB.getCollection("orden");
        DBCursor dbCursor;
        if (basicDBObject == null) {
            dbCursor = channelDBCollection.find();
        } else {
            dbCursor = channelDBCollection.find(basicDBObject);
                }
        ArrayList<String> arrayItems;
        System.out.println("Num Productos:: "+productos.size());
        if (ordenes != null) {
            while (dbCursor.hasNext()) {
                Map map = (dbCursor.next()).toMap();
                arrayItems = convertirJSON(map.get("items").toString());
                System.out.println("Items Orden: "+map.get("items").toString());
                Map<String, Item> items = new HashMap<String, Item>();
                for (int i = 0; i < arrayItems.size(); i += 2) {
                    System.out.println(arrayItems.get(i) + " "+Integer.parseInt(arrayItems.get(i + 1)));
                    System.out.println("Codigo:... "+(productos.get(arrayItems.get(i))).getProductoId());
                    items.put(arrayItems.get(i), new Item(productos.get(arrayItems.get(i)), Integer.parseInt(arrayItems.get(i + 1))));
                }
                ordenes.put(map.get("_id").toString(), new Orden(map.get("_id").toString(), items, new Date()));
            }
        }
    }

    public static void findCliente(DB dB, BasicDBObject basicDBObject,
           Cliente cliente, Map<String, Orden> ordenes, Map<String, Producto> productos) {
        DBCollection channelDBCollection = dB.getCollection("cliente");
        DBCursor dbCursor;
        if (basicDBObject == null) {
            dbCursor = channelDBCollection.find();
        } else {
            dbCursor = channelDBCollection.find(basicDBObject);
        }
        ArrayList<String> arrayOrdenes;
        if (cliente != null) {
            while (dbCursor.hasNext()) {
                Map map = (dbCursor.next()).toMap();
                arrayOrdenes = convertirJSON(map.get("compras").toString());
                for (String arrayOrdene : arrayOrdenes) {
                    findOrden(dB, new BasicDBObject("_id", new ObjectId(arrayOrdene)), ordenes, productos);
                }
                cliente= new Cliente(map.get("_id").toString(), map.get("nombre").toString(), ordenes);
            }
        }
    }

    private static void insertJSON(BufferedReader bufferedReader, DBCollection amazonDBCollection) throws IOException {
        System.out.println("JSON: ");
        amazonDBCollection.insert((DBObject) JSON.parse(bufferedReader.readLine()));
    }

    private static ArrayList<String> convertirJSON(String array) {
        String trama = (array.substring(2, array.length() - 2)).trim();
        //System.out.println("Trama: "+trama);
        String[] filas = trama.split("[}][,][ ][{]");
        ArrayList<String> dato = new ArrayList<String>();
        for (String fila : filas) {
            //System.out.println("Interno: "+fila);//aki un if si hay un array interno
            String[] campos = (fila.trim()).split("[,]");
            for (String campo : campos) {
                String[] temp = (campo.trim()).split(":");
                String var = (temp[temp.length - 1]).trim();
                if (var.contains("\"")) {
                    var = var.substring(1, var.length() - 1);
                }
                if (var.contains("}")) {
                    var = var.substring(0, var.length() - 1);
                }
                if (var.contains("\"")) {
                    var = var.substring(0, var.length() - 1);
                }
                //System.out.println("Var: "+var);
                dato.add(var);
            }
        }
        return dato;
    }
private static void findClientes(DB dB, BasicDBObject basicDBObject,
            Map<String, Cliente> clientes, Map<String, Orden> ordenes, Map<String, Producto> productos) {
        DBCollection channelDBCollection = dB.getCollection("cliente");
        DBCursor dbCursor;
        if (basicDBObject == null) {
            dbCursor = channelDBCollection.find();
        } else {
            dbCursor = channelDBCollection.find(basicDBObject);
        }
        ArrayList<String> arrayOrdenes;
        if (clientes != null) {
            while (dbCursor.hasNext()) {
                Map map = (dbCursor.next()).toMap();
                arrayOrdenes = convertirJSON(map.get("compras").toString());
                for (String arrayOrdene : arrayOrdenes) {
                    findOrden(dB, new BasicDBObject("_id", new ObjectId(arrayOrdene)), ordenes, productos);
                }
                clientes.put(map.get("_id").toString(), new Cliente(map.get("_id").toString(), map.get("nombre").toString(), ordenes));
            }
        }
    }
}
/*
private static void insertOrden(Map<String, Orden> data, DBCollection amazonDBCollection) {
        DBObject amazonDBObject = new BasicDBObject();
        Iterator iter = (data).keySet().iterator();
        while (iter.hasNext()) {
            String keys = iter.next().toString();
            Orden object = (data).get(iter);

            Orden o = (Orden) object;
            amazonDBObject.put("_id", new ObjectId(o.getOrdenId()));
            BasicDBList atrib3DBList = new BasicDBList();
            DBObject atrib3DBObject = null;
            Iterator it = (o.getItems()).keySet().iterator();
            while (it.hasNext()) {
                String key = it.next().toString();
                Item items = (o.getItems()).get(key);

                atrib3DBObject = new BasicDBObject();
                atrib3DBObject.put("producto", new ObjectId(items.getItemId()));
                atrib3DBObject.put("cantidad", items.getCantidad());
                atrib3DBList.add(atrib3DBObject);
            }
            amazonDBObject.put("items", atrib3DBList.toArray());
            amazonDBObject.put("total", o.getTotal());
            amazonDBObject.put("fechaCompra", o.getFechaCompra());
            amazonDBCollection.insert(amazonDBObject);
        }

    }
*/